package com.micai.springboot.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.micai.springboot.dto.MenuDto;
import com.micai.springboot.dto.RoleDto;
import com.micai.springboot.dto.UserDto;
import com.micai.springboot.entity.UserEntity;
import com.micai.springboot.mapper.MenuMapper;
import com.micai.springboot.mapper.RoleMapper;
import com.micai.springboot.mapper.UserMapper;
import com.micai.springboot.mapper.UserRoleMapper;
import com.micai.springboot.service.UserService;
import com.micai.springboot.shiro.PasswordHelper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 描述：
 * <p>
 * Author: 赵新国
 * Date: 2017/10/24 18:36
 */
@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService {

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public List<UserDto> listUsers(String userName) {
        EntityWrapper<UserEntity> entityWrapper = new EntityWrapper<UserEntity>();
        if (userName != null && !StringUtils.isEmpty(userName)) {
            entityWrapper.like("user_name", userName)
                    .or().like("phone", userName)
                    .or().like("email", userName);
        }
        List<UserEntity> userEntities = userMapper.selectList(entityWrapper);
        if (CollectionUtils.isEmpty(userEntities)) {
            return null;
        }
        return toDtos(userEntities);
    }

    @Override
    public Page<UserDto> getUserByPage(int pageNum, int pageSize, String searchParam, String startDate, String endDate) {
        PageHelper.startPage(pageNum, pageSize);
        Map<String, Object> columnMap = new HashMap<String, Object>(16);
        if (searchParam != null && !StringUtils.isEmpty(searchParam)) {
            columnMap.put("user_name", searchParam);
        }
        if (!StringUtils.isBlank(startDate)) {
            columnMap.put("startDate", startDate);
        }
        if (!StringUtils.isBlank(endDate)) {
            columnMap.put("endDate", endDate);
        }
        Page<UserEntity> userEntities = userMapper.findByPage(columnMap);
        if (CollectionUtils.isEmpty(userEntities)) {
            return null;
        }
        Page<UserDto> userDtos = new Page<UserDto>();
        for (UserEntity userEntity : userEntities) {
            UserDto userDto = new UserDto();
            BeanUtils.copyProperties(userEntity, userDto);
            // 加载用户对应的角色列表
            List<Map<String, Object>> roleMaps = roleMapper.getRolesByUserId(userDto.getId());
            if (roleMaps != null) {
                List<RoleDto> roleDtos = new ArrayList<>(roleMaps.size());
                for (Map<String, Object> roleMap : roleMaps) {
                    RoleDto roleDto = new RoleDto();
                    roleDto.setName(roleMap.get("name").toString());
                    roleDtos.add(roleDto);
                }
                userDto.setRoleDtos(roleDtos);
            }
            userDtos.add(userDto);
        }
        return toDto(userEntities, userDtos);
    }

    @Override
    public UserDto save(UserDto userDto) {
        UserEntity bizEntity = new UserEntity();
        BeanUtils.copyProperties(userDto, bizEntity);
        bizEntity.setEnable("1");//默认激活
        if (userMapper.insert(bizEntity) == 1) {
            UserDto bizDto = new UserDto();
            BeanUtils.copyProperties(bizEntity, bizDto);
            return bizDto;
        }
        return null;
    }

    @Override
    public Integer update(UserDto userDto) {
        UserEntity userEntity = new UserEntity();
        BeanUtils.copyProperties(userDto, userEntity);
        return userMapper.updateById(userEntity);
    }

    @Override
    public UserDto getUserById(Long id) {
        UserEntity userEntity = userMapper.selectById(id);
        if (userEntity == null) {
            return null;
        }
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(userEntity, userDto);
        return userDto;
    }

    @Override
    public void delete(UserDto userDto) {
        userMapper.deleteById(userDto.getId());
    }

    @Override
    public UserDto login(String username, String password) {
        UserEntity entity = new UserEntity();
        entity.setUserName(username);
        entity.setPassWord(password);
        UserEntity userEntity = userMapper.selectOne(entity);
        if (userEntity == null) {
            return null;
        }
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(userEntity, userDto);
        return userDto;
    }

    @Override
    public UserDto getUserByParam(String username) {
        UserEntity entity = new UserEntity();
        entity.setUserName(username);
        UserEntity userEntity = userMapper.selectOne(entity);
        if ( userEntity == null) {
            return null;
        }
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(userEntity, userDto);
        return userDto;
    }

    @Override
    public Integer getPermissionCountById(Long id) {
        return userMapper.getPermissionCountById(id);
    }

    @Override
    public UserDto findByUserName(String username) {
        UserEntity entity = new UserEntity();
        entity.setUserName(username);
        UserEntity userEntity = userMapper.selectOne(entity);
        if ( userEntity == null) {
            return null;
        }
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(userEntity, userDto);

        List<Map<String, Object>> roleMaps = roleMapper.getRolesByUserId(userDto.getId());
        if (roleMaps != null) {
            List<RoleDto> roleDtos = new ArrayList<>();
            for (Map<String, Object> roleMap : roleMaps) {
                List<MenuDto> menuDtos = new ArrayList<>();
                RoleDto roleDto = new RoleDto();
                roleDto.setId(Long.valueOf(roleMap.get("id").toString()));
                roleDto.setName(roleMap.get("name").toString());
                roleDto.setCode(roleMap.get("code").toString());
                List<Map<String, Object>> menuMaps = menuMapper.getMenusByRoleId(Long.valueOf(roleMap.get("id").toString()));
                for (Map<String, Object> menuMap : menuMaps) {
                    MenuDto menuDto = new MenuDto();
                    menuDto.setId(Long.valueOf(menuMap.get("id").toString()));
                    menuDto.setName(menuMap.get("name").toString());
                    menuDto.setMenuUrl(menuMap.get("menu_url").toString());
                    menuDtos.add(menuDto);
                }
                roleDto.setMenuDtos(menuDtos);
                roleDtos.add(roleDto);
            }
            userDto.setRoleDtos(roleDtos);
        }
        return userDto;
    }

    @Override
    public boolean lockBatchIds(List<String> ids) {
        boolean flag = false;
        List<UserEntity> userEntities = new ArrayList<>(ids.size());
        ids.forEach(id -> {
            UserEntity userEntity = userMapper.selectById(id);
            if (userEntity != null) {
                userEntity.setEnable("2");//锁定
            }
            userEntities.add(userEntity);
        });
        // 批量更新
        if (updateBatchById(userEntities)) {
            flag = true;
        }
        return flag;
    }

    @Override
    public boolean resetBatchIds(List<String> ids) {
        boolean flag = false;
        List<UserEntity> userEntities = new ArrayList<>(ids.size());
        ids.forEach(id -> {
            UserEntity userEntity = userMapper.selectById(id);
            if (userEntity != null) {
                userEntity.setPassWord("123456");// 默认密码123456
                new PasswordHelper().encryptPassword(userEntity);
            }
            userEntities.add(userEntity);
        });
        // 批量更新
        if (updateBatchById(userEntities)) {
            flag = true;
        }
        return flag;
    }

    @Override
    public boolean unlockBatchIds(List<String> ids) {
        boolean flag = false;
        List<UserEntity> userEntities = new ArrayList<>(ids.size());
        ids.forEach(id -> {
            UserEntity userEntity = userMapper.selectById(id);
            if (userEntity != null) {
                userEntity.setEnable("1");//解锁
            }
            userEntities.add(userEntity);
        });
        // 批量更新
        if (updateBatchById(userEntities)) {
            flag = true;
        }
        return flag;
    }

    @Override
    public List<UserDto> list() {
        List<UserEntity> userEntities = userMapper.selectList(new EntityWrapper<>());
        if (CollectionUtils.isEmpty(userEntities)) {
            return null;
        }
        return toDtos(userEntities);
    }

    private List<UserDto> toDtos(List<UserEntity> userEntities) {
        List<UserDto> userDtos = new ArrayList<UserDto>();
        for (UserEntity userEntity : userEntities) {
            UserDto userDto = new UserDto();
            BeanUtils.copyProperties(userEntity, userDto);
            userDtos.add(userDto);
        }
        return userDtos;
    }

    private Page<UserDto> toDto(Page<UserEntity> userEntities, Page<UserDto> userDtos) {
        BeanUtils.copyProperties(userEntities, userDtos);
        return userDtos;
    }

}
